package jwt

//
//import (
//	"net/http"
//	"sync"
//	"sync/atomic"
//	"time"
//
//	"github.com/golang-jwt/jwt/v5"
//	"github.com/golang-jwt/jwt/v5/request"
//)
//
//const claimHistoryResetDuration = time.Hour * 24
//
//// Use the long enough past time as start time, in case timex.now() - lastTime equals 0.
//var initTime = time.Now().AddDate(-1, -1, -1)
//
//type (
//	// ParseOption defines the method to customize a TokenParser.
//	ParseOption func(parser *TokenParser)
//
//	// A TokenParser is used to parse tokens.
//	TokenParser struct {
//		resetTime     time.Duration
//		resetDuration time.Duration
//		history       sync.Map
//	}
//)
//
//func now() time.Duration {
//	return time.Since(initTime)
//}
//func NewTokenParser(opts ...ParseOption) *TokenParser {
//	parser := &TokenParser{
//		resetTime:     now(),
//		resetDuration: claimHistoryResetDuration,
//	}
//
//	for _, opt := range opts {
//		opt(parser)
//	}
//
//	return parser
//}
//
//// ParseToken parses jwt from given r, with passed in secret and prevSecret.
//func (tp *TokenParser) ParseToken(r *http.Request, secret, prevSecret string) (*jwt.Token, error) {
//	var jwt *jwt.Token
//	var err error
//
//	if len(prevSecret) > 0 {
//		count := tp.loadCount(secret)
//		prevCount := tp.loadCount(prevSecret)
//
//		var first, second string
//		if count > prevCount {
//			first = secret
//			second = prevSecret
//		} else {
//			first = prevSecret
//			second = secret
//		}
//
//		jwt, err = tp.doParseToken(r, first)
//		if err != nil {
//			jwt, err = tp.doParseToken(r, second)
//			if err != nil {
//				return nil, err
//			}
//
//			tp.incrementCount(second)
//		} else {
//			tp.incrementCount(first)
//		}
//	} else {
//		jwt, err = tp.doParseToken(r, secret)
//		if err != nil {
//			return nil, err
//		}
//	}
//
//	return jwt, nil
//}
//
//func (tp *TokenParser) doParseToken(r *http.Request, secret string) (*jwt.Token, error) {
//	return request.ParseFromRequest(r, request.AuthorizationHeaderExtractor,
//		func(jwt *jwt.Token) (any, error) {
//			return []byte(secret), nil
//		}, request.WithParser(newParser()))
//}
//
//func (tp *TokenParser) incrementCount(secret string) {
//	now := now()
//	if tp.resetTime+tp.resetDuration < now {
//		tp.history.Range(func(key, value any) bool {
//			tp.history.Delete(key)
//			return true
//		})
//	}
//
//	value, ok := tp.history.Load(secret)
//	if ok {
//		atomic.AddUint64(value.(*uint64), 1)
//	} else {
//		var count uint64 = 1
//		tp.history.Store(secret, &count)
//	}
//}
//
//func (tp *TokenParser) loadCount(secret string) uint64 {
//	value, ok := tp.history.Load(secret)
//	if ok {
//		return *value.(*uint64)
//	}
//
//	return 0
//}
//
//// WithResetDuration returns a func to customize a TokenParser with reset duration.
//func WithResetDuration(duration time.Duration) ParseOption {
//	return func(parser *TokenParser) {
//		parser.resetDuration = duration
//	}
//}
//
//func newParser() *jwt.Parser {
//	return jwt.NewParser(jwt.WithJSONNumber())
//}
